package App.OO.ClientView;

import App.Model.*;
import App.Model.Interface.MessageType;
import App.Model.Tool.DosTool;
import App.Model.Tool.SwingUtil;
import App.Model.message.Message;
import App.OO.service.OOFileCService;
import App.OO.service.OOLoginSignService;
import App.OO.service.OOTalkService;
import com.alibaba.fastjson.JSON;

import javax.swing.Box;

import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;
import javax.swing.filechooser.FileSystemView;
import javax.swing.text.AbstractDocument;
import java.awt.*;
import java.awt.event.*;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

/*主要功能界面*/
public class OOMainFrame extends JFrame {
    private String userId = null;
    private OOLoginSignService loginService = null;
    private OOTalkService talkService = new OOTalkService();
    private OOFileCService fileCService = new OOFileCService();
    private boolean loop = true;
    private String key = "";
    private JLabel jNewmessage = new JLabel();//右下角显示通用消息
    private JPanel panelCenter = new JPanel();//中心动态生成的对话内容
    private JList jUserList = new JList();//用于显示用户在线状态的列表
    private UserListModel userListModel = new UserListModel();//在线状态列表jUserList的配合
    private UserListCellRenderer userListCellRenderer = new UserListCellRenderer();//jUserList的着色器
    private JPanel pCenter;
    private String nowUser;//当前聊天对象
    private HashMap<String, List<Message>> conversations;//储存聊天对话(key:与你对话的user)
    private JScrollPane jScrollPane;

    public OOMainFrame(OOLoginSignService loginService) {
        this.userId = loginService.getUser().getUserId();
        this.loginService = loginService;

        //实例化该窗体的类的的时候就应该将conversations加载进来
        conversations = ArisuClientDB.readConversationToFile(userId);
        if (conversations == null) {
            conversations = new HashMap<>();
        }
    }

    public void ShowMenu() {
        while (loop) {
            System.out.println(": 1 : 显示在线用户列表");
            System.out.println(": 2 : 群发");
            System.out.println(": 3 : 私聊");
            System.out.println(": 4 : 发送文件");
            System.out.println(": 5 : 获取离线消息");
            System.out.println(": 9 : 退出系统");
            key = DosTool.readString(1);
            switch (key) {
                case "1"://显示在线用户列表
                    System.out.println("显示在线用户列表");
                    loginService.getUserAndOnlineList();
                    break;
                case "2"://群发
                    System.out.println("群发");
                    System.out.println("请输入想对大家说的话: ");
                    String content = DosTool.readString(1000);

                    talkService.sendTalkAll(content, userId);
                    break;
                case "3"://私聊
                    System.out.println("私聊");
                    //选择聊天对象    (当前仅能在线聊天)
                    loginService.getUserAndOnlineList();
                    System.out.println("请输入想要聊天的用户号: ");
                    String talkToId = DosTool.readString(50);

                    System.out.print("请输入想要说的话: ");
                    String talkContent = DosTool.readString(1000);

                    talkService.sendTalkOne(talkContent, userId, talkToId);
                    break;
                case "4"://发送文件
                    //由于源码和逻辑改变,dos界面失效
                    //存在问题: 未检测文件是否存在,未检测路径是否存在......
//                    System.out.println("发送文件");
//                    System.out.println("发送的目标对象:");
//                    String getterId = DosTool.readString(100);
//                    System.out.println("发送的文件源地址(d:\\xx.jpg): ");
//                    String src = DosTool.readString(100);
//                    System.out.println("发送到目标的磁盘位置(d:\\xx.jpg): ");
//                    String dest = DosTool.readString(100);
//
//                    //此处发送的文件未进行验证
//                    fileCService.sendFileToOne(src, dest, userId, getterId);
                    break;
                case "5"://获取离线消息
                    OOTalkService.getOfflineMessage(userId);
                    break;
                case "9"://退出
                    System.out.println("退出系统");
                    loop = false;
                    //发送退出消息到服务器端
                    loginService.exitClient();
                    break;
                default:
            }

        }
    }

    public void showMainFrame() {
        //窗口初始化
        Font textFont = new Font("宋体", Font.BOLD, 17);
        setTitle("OO");
        setBounds(400, 300, 650, 375);    //设置窗体显示位置和大小
        setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
        setResizable(false);

        //程序icon标
        setIconImage(new ImageIcon("src\\main\\resources\\recourse\\OO.png").getImage());

        //SOUTH通用消息框输入框
        JPanel panelSouth = new JPanel(new FlowLayout(FlowLayout.RIGHT, 10, 10));
        jNewmessage.setText("消息null");
        jNewmessage.setFont(textFont);
        panelSouth.add(jNewmessage);

        //WEST所有用户列表
        userListModel = new UserListModel();
        jUserList = new JList(userListModel);
        jUserList.setBorder(BorderFactory.createTitledBorder("用户列表"));
        //userListCellRenderer = new UserListCellRenderer();
        jUserList.setCellRenderer(userListCellRenderer);
        jUserList.setFixedCellWidth(60);
        jUserList.setBackground(Color.lightGray);
        jUserList.setSelectionForeground(Color.cyan);
        userListCellRenderer.conformUser = ArisuClientDB.readConformToFile(userId);//读取外部文件中存储的消息提示

        //CENTER聊天框
        panelCenter = new JPanel(new BorderLayout());
            //north显示聊天者与聊天对象
        JLabel jContext = new JLabel(" " + userId + " <--> " + nowUser, SwingConstants.LEFT);
        jContext.setFont(new Font("微软雅黑", Font.PLAIN, 13));
        panelCenter.add(jContext, BorderLayout.NORTH);
            //center消息显示区域
        pCenter = new JPanel();
        pCenter.setLayout(new BoxLayout(pCenter, BoxLayout.Y_AXIS));
        JLabel jFirstLabel = new JLabel("<html><center>" + userId + "</center></html>", SwingConstants.CENTER);
        LineBorder border = new LineBorder(Color.DARK_GRAY, 8);
        jFirstLabel.setBorder(border);
        jFirstLabel.setFont(textFont);
        pCenter.add(jFirstLabel);
        jScrollPane = new JScrollPane(pCenter);//生成一个滚动的聊天框
        jScrollPane.getVerticalScrollBar().setUI(new JScrollPaneBarUI());//更改bar的ui
        jScrollPane.getVerticalScrollBar().setUnitIncrement(30);
        jScrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);//水平方向禁止
        panelCenter.add(jScrollPane, BorderLayout.CENTER);
            //south编辑框与发送按钮区域
        Box box = Box.createHorizontalBox();
        Box boxBtn = Box.createVerticalBox();
        JButton jSubmitBtn = new JButton("发送");
        JButton jFileBtn = new JButton("表情");
        Font csFont = new Font("微软雅黑", Font.BOLD, 13);
        jSubmitBtn.setFont(csFont);
        jFileBtn.setFont(csFont);
                //消息输入框的自定义行为
        JTextArea editorField = new JTextArea(3,2);
        editorField.setLineWrap(true);
        editorField.setBackground(new Color(245, 245, 245));
        ((AbstractDocument)editorField.getDocument()).setDocumentFilter(new LimitFilter(1000));//限制最大输入
        JScrollPane editorFieldPane = new JScrollPane(editorField);
        editorFieldPane.getVerticalScrollBar().setUI(new JScrollPaneBarUI());
        editorFieldPane.getVerticalScrollBar().setUnitIncrement(4);
            //south编辑框的加入
        box.add(editorFieldPane);
        boxBtn.add(jSubmitBtn);
        boxBtn.add(jFileBtn);
        box.add(boxBtn);
        panelCenter.add(box, BorderLayout.SOUTH);

        //布局
        setLayout(new BorderLayout());
        add(panelCenter, BorderLayout.CENTER);
        add(new JScrollPane(jUserList), BorderLayout.WEST);
        add(panelSouth, BorderLayout.SOUTH);
        setVisible(true);

        //事件处理
        jSubmitBtn.addActionListener(e -> {//发送消息
            putTalkMessageToService(editorField.getText());
            editorField.setText("");
        });

        jUserList.addMouseListener(new MouseAdapter() {//双击跳转到对应的聊天用户并在聊天框中生成消息
            public String clickedUser = "";

            @Override//右键用户选项
            public void mouseReleased(MouseEvent e) {
                if (e.isPopupTrigger()) {
                    int index = jUserList.locationToIndex(e.getPoint());
                    clickedUser = userListModel.getElementAt(index).toString().replace("●", "");
                    System.out.println(clickedUser);
                    if (index != -1) { // 确保点击在列表项上
                        userListCellRenderer.setNowClicked(index);
                        jUserList.repaint(); // 重新绘制列表以显示更改
                    }
                    showPopupMenu(e);
                }
            }

            private void showPopupMenu(MouseEvent e) {
                JPopupMenu popupMenu = new JPopupMenu();
                // 为“查看用户信息”菜单项添加事件监听器
                JMenuItem viewUserInfoItem = new JMenuItem("查看用户信息");
                viewUserInfoItem.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        //向服务器获取用户信息
                        talkService.getUserDetail(clickedUser, userId);
                    }
                });
                popupMenu.add(viewUserInfoItem);

//                // 为“邀请加入群聊(未完成)”菜单项添加事件监听器
//                JMenuItem inviteToChatItem = new JMenuItem("邀请加入群聊(未完成)");
//                inviteToChatItem.addActionListener(new ActionListener() {
//                    @Override
//                    public void actionPerformed(ActionEvent e) {
//                        System.out.println("邀请加入群聊菜单项被点击");
//                        // TODO: 实现邀请加入群聊的逻辑
//
//                    }
//                });
//                popupMenu.add(inviteToChatItem);

                // 为“发送文件(未完成)”菜单项添加事件监听器
                JMenuItem driveFileToUser = new JMenuItem("发送文件");
                driveFileToUser.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        // TODO: 实现发送文件的逻辑
                        if(userId.equals(clickedUser)){//自己不应该给自己发送文件(同步在线的情况解决了再说)
                            JOptionPane.showMessageDialog(null,
                                    "不能给自己发送文件!", "警告", JOptionPane.WARNING_MESSAGE);
                            return;
                        }
                        FileSystemView fsv = FileSystemView.getFileSystemView();
                        JFileChooser fileChooser = new JFileChooser();
                        fileChooser.setCurrentDirectory(fsv.getHomeDirectory());
                        int result = fileChooser.showOpenDialog(null);
                        if(result == JFileChooser.APPROVE_OPTION) {
                            String filename = fileChooser.getSelectedFile().getName();
                            String src = fileChooser.getSelectedFile().getAbsolutePath();//文件路径
                            long fileLength = fileChooser.getSelectedFile().length();
                            String fileLengthStr = DosTool.swapFileLength(fileLength);

                            int option = JOptionPane.showConfirmDialog(null,
                                    ("向 " + clickedUser + " 发送 " + filename  + " 文件? 约" + fileLengthStr)
                                            , "发送文件", JOptionPane.YES_NO_OPTION, JOptionPane.INFORMATION_MESSAGE);
                            if (option == JOptionPane.YES_OPTION) {
                                if(fileLength > 209715200 && !userListModel.isOnline(clickedUser)){//大于200mb且用户不在线(拒绝发送)
                                    //服务器资源有限,超过200mb的资源只能在线发
                                    JOptionPane.showMessageDialog(null,
                                            "服务器存储资源有限,超过200mb的文件请双方在线时发送！", "警告", JOptionPane.WARNING_MESSAGE);
                                } else if (fileLength > 209715200 && userListModel.isOnline(clickedUser)) {//大于200mb但用户在线(请求对方同意后在线发送)
                                    System.out.println("功能未完成");
                                    //在线发送
                                } else if(fileLength < 209715200){//小于200mb(默认存储到服务器,用户随拿随取)
                                    //会储存在服务器上,并附带给发送一个普通消息给用户
                                    fileCService.sendFileToOne(src,filename,userId,clickedUser,1,fileLengthStr);//用服务器暂存的方式发送

                                } else{JOptionPane.showMessageDialog(null,"情况特殊,无法服务", "警告", JOptionPane.WARNING_MESSAGE);}

                                //文件已发送,模拟一个message保存到本地
                                Message message = new Message();
                                message.setContent("你向对方发送了一个文件 " + filename + "  " + fileLengthStr);
                                message.setFileuniquenum(0);//这个东西本地不需要
                                message.setSender(userId);
                                message.setGetter(clickedUser);
                                message.setSendTime(new Date());
                                message.setMesType(MessageType.MESSAGE_FILE_MSG_CONFORM);
                                if (conversations.containsKey(clickedUser) && conversations.get(clickedUser) != null) {
                                    conversations.get(clickedUser).add(message);
                                } else {
                                    //第一次聊天时删除显示的"开始聊天吧"字样
                                    if(nowUser.equals(clickedUser)){
                                        pCenter.removeAll();
                                    }
                                    List<Message> mTemp = new ArrayList<>();
                                    mTemp.add(message);
                                    conversations.put(clickedUser, mTemp);
                                }
                                addTalkBox(message);
                            }
                        }
                    }
                });
                popupMenu.add(driveFileToUser);

                // 为“删除所有聊天信息”菜单项添加事件监听器
                JMenuItem deleteAllChatsItem = new JMenuItem("删除本地聊天信息");
                deleteAllChatsItem.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        System.out.println("删除所有聊天信息菜单项被点击");
                        if (conversations.containsKey(clickedUser)) {
                            int option = JOptionPane.showConfirmDialog
                                    (null, "请问你是否要删除与 " + clickedUser + " 的 " + conversations.get(clickedUser).size() + " 条聊天记录"
                                            , "警告", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE);
                            if (option == JOptionPane.YES_OPTION) {
                                //执行删除操作并保存
                                conversations.remove(clickedUser);
                                //ArisuClientDB.saveConversationToFile(userId,conversations);//可以不用保存,在用户关闭的时候自动保存
                                if (nowUser.equals(clickedUser)) {
                                    pCenter.removeAll();
                                    jFirstLabel.setText("<html><center>开始新的对话吧</center></html>!");
                                    jFirstLabel.setVerticalTextPosition(JLabel.CENTER);
                                    jFirstLabel.setFont(textFont);
                                    pCenter.add(jFirstLabel);
                                    pCenter.revalidate();
                                    pCenter.repaint();
                                }
                            }
                        }else{System.out.println("与该用户不存在对话");}
                    }
                });
                popupMenu.add(deleteAllChatsItem);

                //其他初始化
                popupMenu.addPopupMenuListener(new PopupMenuListener() {
                    public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
                    }

                    public void popupMenuCanceled(PopupMenuEvent e) {
                    }

                    @Override
                    public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
                        userListCellRenderer.setNowClicked(-1);
                        jUserList.repaint();
                    }
                });
                popupMenu.show(e.getComponent(), e.getX(), e.getY());
            }

            @Override//双击到用户对话
            public void mouseClicked(MouseEvent e) {
                if (e.getClickCount() == 2) {

                    int index = jUserList.locationToIndex(e.getPoint());
                    if (index != -1) {
                        //如果有则去除最左边的'●'
                        nowUser = (userListModel.getElementAt(index)).replace("●", "");
                        jContext.setText(" " + userId + " <--> " + nowUser);
                        System.out.println("当前聊天对象: " + nowUser);
                        userListCellRenderer.nowUser = nowUser;
                        jUserList.repaint();

                        //生成与该用户的聊天消息
                        if (!showMessageList()) {
                            System.out.println(nowUser + " 未与你存在对话");
                            jFirstLabel.setText("<html><center>开始新的对话吧</center></html>!");
                            jFirstLabel.setVerticalTextPosition(JLabel.CENTER);
                            jFirstLabel.setFont(textFont);
                            pCenter.add(jFirstLabel);
                            pCenter.revalidate();
                            pCenter.repaint();
                        }
                        //在UserListCellRenderer中清除当前用户的提示
                        userListCellRenderer.removeConformUser(nowUser);
                    }
                }
            }
        });
        //添加键盘处理事件,回车键为发送信息
        editorField.addKeyListener(new KeyAdapter() {
            @Override
            public void keyPressed(KeyEvent e) {
                if (e.getKeyCode() == KeyEvent.VK_ENTER) {
                    // 处理回车事件
                    putTalkMessageToService(editorField.getText());
                    editorField.setText("");
                    e.consume(); // 阻止默认行为
                }
            }
        });
        //添加窗口关闭事件:使服务器正常运行
        addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                //保存聊天数据
                if (conversations != null) {
                    System.out.println("保存聊天文件");
                    ArisuClientDB.saveConversationToFile(userId, conversations);
                }
                //保存离线通知
                if (userListCellRenderer.conformUser != null) {
                    System.out.println("保存新消息通知");
                    ArisuClientDB.saveConformToFile(userId, userListCellRenderer.conformUser);
                }
                if (ArisuClientDB.getUserHeaders() != null) {//头像
                    ArisuClientDB.saveHeadersToFile();
                }

                //关闭窗口
                loginService.exitClient();
                super.windowClosing(e);
            }
        });
    }

    private void putTalkMessageToService(String content) {
        if (nowUser == null) {
            return;
        }
        //为了方便储存这个包,打包后发出
        if (!content.equals("")) {
            Message message = new Message();
            message.setContent(content);
            message.setSender(userId);
            message.setGetter(nowUser);
            message.setSendTime(new Date());
            message.setMesType(MessageType.MESSAGE_COMM_MSG);
            //保存到本地并发送
            if (conversations.containsKey(nowUser) && conversations.get(nowUser) != null) {
                conversations.get(nowUser).add(message);
            } else {
                //第一次聊天时删除显示的"开始聊天吧"字样
                pCenter.removeAll();

                List<Message> mTemp = new ArrayList<>();
                mTemp.add(message);
                conversations.put(nowUser, mTemp);
            }
            if(!nowUser.equals(userId)){ //当对话者是自己时,不用发送到服务器,只需要保存下来就可以了
                talkService.sendTalkOne(message);
            }
            addTalkBox(message);
            //滚到底部
        }

    }

    public void getMessageAtService(Message message) {
        //收取到在线消息的处理
        System.out.println(message.getGetter() + " 收到消息： " + message.getSender() + "说：" + message.getContent());
        System.out.println("nowUser: " + nowUser);
        //整理从服务器接受到的message
        //发送并保存到本地
        if (conversations.containsKey(message.getSender()) && conversations.get(message.getSender()) != null) {
            conversations.get(message.getSender()).add(message);
        } else {
            //第一次聊天时删除显示的"开始聊天吧"字样
            if (nowUser.equals(message.getSender())) {
                pCenter.removeAll();
            }
            //创建消息再保存本地
            List<Message> mTemp = new ArrayList<>();
            mTemp.add(message);
            conversations.put(message.getSender(), mTemp);
        }
        //接受到消息后在加入消息列表并重绘(简化代码来自showMessageList)
        if (message.getSender().equals(nowUser)) {
            addTalkBox(message);
        } else {
            //当发送者没有与接受者对话时
            //userListModel.confirmThisUser(message.getSender());
            userListCellRenderer.addConformUser(message.getSender());
            jUserList.revalidate();
            jUserList.repaint();
        }

    }

    public void addTalkBox(Message message) {
        if(message.getMesType().equals(MessageType.MESSAGE_COMM_MSG_MENTION)){
            JLabel jMentionLabel = new JLabel("<html><center>.       " + message.getContent() + "</center></html>!");
            jMentionLabel.setVerticalTextPosition(JLabel.CENTER);
            jMentionLabel.setFont(new Font("微软雅黑", Font.PLAIN, 12));
            pCenter.add(Box.createVerticalStrut(3));
            pCenter.add(jMentionLabel);
            jScrollPane.getViewport().setViewPosition(//滚到底部
                    new Point(0, jScrollPane.getVerticalScrollBar().getMaximum()));
            jScrollPane.getViewport().setViewPosition(//滚到底部
                    new Point(0, jScrollPane.getVerticalScrollBar().getMaximum()));
            return;
        }
        //创建单独的对话盒子 在发送对话后的更新与接受对话时的更新时用
        //当发送者正在和接收者对话时
        //一次性生成头像等数据(数据为本地数据,未前往服务端更新)
        ImageIcon myHeaderImage = ArisuClientDB.getHeaderImg(userId);
        if(myHeaderImage == null){
            myHeaderImage = SwingUtil.createAutoAdjustIcon
                    ("src\\main\\resources\\recourse\\header\\header_null.png", true);//实例化ImageIcon 对象
        }else{
            myHeaderImage = SwingUtil.createAutoAdjustIcon(myHeaderImage.getImage(),true);
        }
        //myHeaderImage = SwingUtil.createBorderToImg(myHeaderImage,Color.gray,2);
        ImageIcon opHeaderImage = ArisuClientDB.getHeaderImg(nowUser);
        if(opHeaderImage == null){
            opHeaderImage = SwingUtil.createAutoAdjustIcon
                    ("src\\main\\resources\\recourse\\header\\header_null.png", true);//实例化ImageIcon 对象
        }else{
            opHeaderImage = SwingUtil.createAutoAdjustIcon(opHeaderImage.getImage(),true);
        }
        //opHeaderImage = SwingUtil.createBorderToImg(opHeaderImage,Color.gray,2);

        ImageIcon fileIcon = SwingUtil.createAutoAdjustIcon("src\\main\\resources\\recourse\\fileMention.png", true);
        Font windows15Font = new Font("微软雅黑", Font.BOLD, 15);
        EmptyBorder emptyBorder = new EmptyBorder(0, 0, 0, 10);//头像左边空白区域
        EmptyBorder imgBorder = new EmptyBorder(7, 7, 7, 7);//头像区域
        EmptyBorder textBorder = new EmptyBorder(11, 5, 11, 2);//头像右边>区域

        Box bInnerEach = Box.createHorizontalBox();
        JTextArea jLEach = new JTextArea(message.getContent());
        jLEach.setFont(new Font("微软雅黑", Font.BOLD, 12));
        jLEach.setLineWrap(true);
        jLEach.setWrapStyleWord(true);
        jLEach.setEditable(false);
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        String formattedDate = formatter.format(message.getSendTime());
        //这种风格为都在左边
        if (message.getSender().equals(userId)) {//当消息为发送者发出的时候
            jLEach.setBackground(new Color(95, 201, 105));
        }
        jLEach.setBorder
                (BorderFactory.createTitledBorder(message.getSender() + "  " + formattedDate));
        bInnerEach.setAlignmentX(Component.LEFT_ALIGNMENT);

        //空白填充
        JLabel jEmpty = new JLabel("");
        jEmpty.setBorder(emptyBorder);
        //用户头像
        JLabel jLImg;
        if(message.getSender().equals(nowUser)){
            jLImg = new JLabel(opHeaderImage);
        }
        else jLImg = new JLabel(myHeaderImage);
        //jLImg.setBorder(BorderFactory.createLineBorder(Color.gray, 3));
        jLImg.setPreferredSize(new Dimension(40, 40));
        jLImg.setBorder(imgBorder);
        //模拟对话的冒号
        JLabel jLText = new JLabel(">");
        jLText.setFont(windows15Font);
        jLText.setBorder(textBorder);

        //加入组合块中
        bInnerEach.add(jEmpty);
        bInnerEach.add(jLImg);
        bInnerEach.add(jLText);

        //文件类型消息默认加文件图片
        if(message.getMesType().equals(MessageType.MESSAGE_FILE_MSG_CONFORM)
                ||message.getMesType().equals(MessageType.MESSAGE_FILE_MSG_NOTGET_SUCCEED)
                ||message.getMesType().equals(MessageType.MESSAGE_FILE_MSG_GET_SUCCEED)){
            JLabel jFileMention = new JLabel(fileIcon);
            jFileMention.setPreferredSize(new Dimension(40,40));
            bInnerEach.add(jFileMention);
        }

        bInnerEach.add(jLEach);
        //文件接受提醒的按钮
        if(message.getMesType().equals(MessageType.MESSAGE_FILE_MSG_CONFORM)){
            if(!message.getSender().equals(userId)){
                bInnerEach.add(createFileMessageBox(message));
            }
        }

        //加入垂直代码块后重绘
        pCenter.add(Box.createVerticalStrut(10));
        pCenter.add(bInnerEach);

        //调用两次才会真正到达最底部
        jScrollPane.getViewport().setViewPosition(//滚到底部
                new Point(0, jScrollPane.getVerticalScrollBar().getMaximum()));
        jScrollPane.getViewport().setViewPosition(//滚到底部
                new Point(0, jScrollPane.getVerticalScrollBar().getMaximum()));
    }

    public boolean showMessageList() {
        //不用判断nowUser，nowUser应该已经被判断存在
        //清空原有的bCenter的部分
        pCenter.removeAll();
        List<Message> nowUserList = conversations.get(nowUser);
        if (nowUserList == null) {
            return false;
        }
        //一次性生成头像等数据(数据为本地数据,未前往服务端更新)
        ImageIcon myHeaderImage = ArisuClientDB.getHeaderImg(userId);
        //myHeaderImage = SwingUtil.createBorderToImg(myHeaderImage,Color.black,20);
        if(myHeaderImage == null){
            myHeaderImage = SwingUtil.createAutoAdjustIcon
                    ("src\\main\\resources\\recourse\\header\\header_null.png", true);//实例化ImageIcon 对象
        }else{
            myHeaderImage = SwingUtil.createAutoAdjustIcon(myHeaderImage.getImage(),true);
        }
        ImageIcon opHeaderImage = ArisuClientDB.getHeaderImg(nowUser);
        //opHeaderImage = SwingUtil.createBorderToImg(opHeaderImage,Color.black,20);
        if(opHeaderImage == null){
            opHeaderImage = SwingUtil.createAutoAdjustIcon
                    ("src\\main\\resources\\recourse\\header\\header_null.png", true);//实例化ImageIcon 对象
        }else{
            opHeaderImage = SwingUtil.createAutoAdjustIcon(opHeaderImage.getImage(),true);
        }

        ImageIcon fileIcon = SwingUtil.createAutoAdjustIcon("src\\main\\resources\\recourse\\fileMention.png", true);
        //ImageIcon autoAdjustIcon = SwingUtil.createAutoAdjustIcon("src\\main\\resources\\recourse\\header\\header_null.png", true);
        Font windows15Font = new Font("微软雅黑", Font.BOLD, 15);
        EmptyBorder emptyBorder = new EmptyBorder(0, 0, 0, 10);//头像左边空白区域
        EmptyBorder imgBorder = new EmptyBorder(7, 7, 7, 7);//头像区域
        EmptyBorder textBorder = new EmptyBorder(11, 5, 11, 2);//头像右边>区域
        //将过去的聊天消息动态地生成并且显示出来
        for (Message mEach : nowUserList) {
            if(mEach.getMesType().equals(MessageType.MESSAGE_COMM_MSG_MENTION)){
                JLabel jMentionLabel = new JLabel("<html><center>.       " + mEach.getContent() + "</center></html>!");
                jMentionLabel.setVerticalTextPosition(JLabel.CENTER);
                jMentionLabel.setFont(new Font("微软雅黑", Font.PLAIN, 12));
                pCenter.add(Box.createVerticalStrut(3));
                pCenter.add(jMentionLabel);
                continue;
            }
            Box bInnerEach = Box.createHorizontalBox();
            JTextArea jLEach = new JTextArea(mEach.getContent());
            jLEach.setFont(new Font("微软雅黑", Font.BOLD, 12));
            jLEach.setLineWrap(true);
            jLEach.setWrapStyleWord(true);
            jLEach.setEditable(false);

            //加工发送日期
            SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm");
            String formattedDate = formatter.format(mEach.getSendTime());

            //这种风格为都在左边
            if (mEach.getSender().equals(userId)) {//当消息为发送者发出的时候
                jLEach.setBackground(new Color(95, 201, 105));
            }
            jLEach.setBorder
                    (BorderFactory.createTitledBorder(mEach.getSender() + "  " + formattedDate));
            bInnerEach.setAlignmentX(Component.LEFT_ALIGNMENT);

            //空白填充
            JLabel jEmpty = new JLabel("");
            jEmpty.setBorder(emptyBorder);
            //用户头像
            JLabel jLImg;
            if(mEach.getSender().equals(nowUser)){
                jLImg = new JLabel(opHeaderImage);
            }
            else jLImg = new JLabel(myHeaderImage);
            //jLImg.setBorder(BorderFactory.createLineBorder(Color.gray, 3));
            jLImg.setPreferredSize(new Dimension(40, 40));
            jLImg.setBorder(imgBorder);
            //模拟对话的冒号
            JLabel jLText = new JLabel(">");
            jLText.setFont(windows15Font);
            jLText.setBorder(textBorder);

            //加入组合块中
            bInnerEach.add(jEmpty);
            bInnerEach.add(jLImg);
            bInnerEach.add(jLText);

            //文件类型消息默认加文件图片
            if(mEach.getMesType().equals(MessageType.MESSAGE_FILE_MSG_CONFORM)
                    ||mEach.getMesType().equals(MessageType.MESSAGE_FILE_MSG_NOTGET_SUCCEED)
                    ||mEach.getMesType().equals(MessageType.MESSAGE_FILE_MSG_GET_SUCCEED)){
                JLabel jFileMention = new JLabel(fileIcon);
                jFileMention.setPreferredSize(new Dimension(40,40));
                bInnerEach.add(jFileMention);
            }

            bInnerEach.add(jLEach);
            //当消息为文件提醒时,加入两个确定取消的按钮

            //文件接受提醒的按钮
            if(mEach.getMesType().equals(MessageType.MESSAGE_FILE_MSG_CONFORM)){
                if(!mEach.getSender().equals(userId)){
                    //System.out.println(JSON.toJSONString(mEach));
                    bInnerEach.add(createFileMessageBox(mEach));
                }
            }

            //加入垂直代码块后重绘
            pCenter.add(Box.createVerticalStrut(10));
            pCenter.add(bInnerEach);

            jScrollPane.getViewport().setViewPosition(//滚到底部
                    new Point(0, jScrollPane.getVerticalScrollBar().getMaximum()));
            jScrollPane.repaint();
        }
        return true;
    }

    private Box createFileMessageBox(Message message){
        Box bFileMention = Box.createVerticalBox();
        JButton jSureBtn = new JButton("接受");
        JButton jNotBtn = new JButton("取消");
        bFileMention.add(jSureBtn);
        bFileMention.add(jNotBtn);
        jSureBtn.addActionListener(e -> {//接收文件
            jSureBtn.setVisible(false);
            jNotBtn.setVisible(false);
            //userId 向 服务器 获取 uniqueNum编号的文件
            fileCService.getSourceAtServiceFile(userId,message.getSender(),message.getFileuniquenum(),message.getDest(),true);
            Message mentionMessage = new Message();
            mentionMessage.setMesType(MessageType.MESSAGE_COMM_MSG_MENTION);
            mentionMessage.setSendTime(new Date());
            String fileName = DosTool.SplitFileName(message.getDest());
            mentionMessage.setContent("接受了对方文件 " + fileName);
            mentionMessage.setSender(userId);
            mentionMessage.setGetter(nowUser);
            //寻找到目标消息然后将其状态改为接收文件成功
            List<Message> messageList = conversations.get(nowUser);
            if(messageList == null){
                return;
            }
            for (int i = messageList.size() - 1;i>=0;i--) {
                Message eMsg = messageList.get(i);
                if(eMsg.getFileuniquenum() == message.getFileuniquenum()){
                    System.out.println(JSON.toJSONString(eMsg));
                    eMsg.setMesType(MessageType.MESSAGE_FILE_MSG_GET_SUCCEED);
                    break;
                }
            }
            messageList.add(mentionMessage);
            addTalkBox(mentionMessage);//将提醒消息加入显示对话列表中
        });
        jNotBtn.addActionListener(e -> {//拒绝文件
            jSureBtn.setVisible(false);
            jNotBtn.setVisible(false);
            //userId 向 服务器 拒收 uniqueNum编号的文件
            fileCService.getSourceAtServiceFile(userId,message.getSender(),message.getFileuniquenum(),message.getDest(),false);
            Message mentionMessage = new Message();
            mentionMessage.setMesType(MessageType.MESSAGE_COMM_MSG_MENTION);
            mentionMessage.setSendTime(new Date());
            String fileName = DosTool.SplitFileName(message.getDest());
            mentionMessage.setContent("拒绝了对方文件 " + fileName);
            mentionMessage.setSender(userId);
            mentionMessage.setGetter(nowUser);
            //寻找到目标消息然后将其状态改为拒绝文件成功
            List<Message> messageList = conversations.get(nowUser);
            if(messageList == null){
                return;
            }
            for (int i = messageList.size() - 1;i>=0;i--) {
                Message eMsg = messageList.get(i);
                if(eMsg.getFileuniquenum() == message.getFileuniquenum()){
                    eMsg.setMesType(MessageType.MESSAGE_FILE_MSG_NOTGET_SUCCEED);
                    break;
                }
            }
            messageList.add(mentionMessage);
            addTalkBox(mentionMessage);//将提醒消息加入显示对话列表中
        });
        return bFileMention;
    }


    public void updateUserList(String userList) {//更新用户在线列表
        userListModel.updateList(userList);//在列表中更新数据
        jUserList.revalidate(); // 重新验证布局
        jUserList.repaint(); // 重新绘制组件
    }

    public String getUserId() {
        return userId;
    }

    public OOLoginSignService getLoginService() {
        return loginService;
    }

    public void setLoginService(OOLoginSignService loginService) {
        this.loginService = loginService;
        this.userId = loginService.getUser().getUserId();
    }

    public void setTextMessage(String data) {//更改提示文本的text值
        jNewmessage.setText("" + data);
    }

    public HashMap<String, List<Message>> getConversations() {
        return conversations;
    }

    public void updateConformList(List<String> senders) {
        userListCellRenderer.addConformUserToService(senders);
    }
}
